package chances.declare.web;

import java.io.File;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import chances.commons.crypto.CodeUtils;
import chances.declare.entity.CPContent;
import chances.declare.service.CPContentService;
import chances.declare.service.WriteContentExcelService;
import chances.system.json.JsonResponse;
import chances.system.json.RestfulJson;
import chances.system.log.entity.ActionLog;
import chances.system.log.entity.CompareLog;
import chances.system.operator.entity.EnumData;
import chances.system.operator.entity.Operator;
import chances.system.operator.entity.Oplog;
import chances.system.operator.repo.EnumDataRepository;
import chances.system.operator.web.MgmtInfoController;
import chances.system.service.EnumService;

/**
 * @Author WangCC
 * @Date 2017年7月28日 下午5:06:01 chances.declare.web
 * @Version 1.0
 */

@RestController
public class CPContentController {

    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();

    private static final Logger logger = LoggerFactory.getLogger(MgmtInfoController.class);

    @Autowired
    private CPContentService contentService;
    @Autowired
    private EnumDataRepository enumDataRepository;
    @Autowired
    private EnumService enumService;
    
    @RequestMapping(path = "/declare/content/findContent", method = RequestMethod.GET)
    public RestfulJson findCPContent(HttpServletRequest request,
            @RequestParam(name = "page", defaultValue = "0") int page,
            @RequestParam(name = "size", defaultValue = "10") int size,
            @RequestParam(name = "field", defaultValue = "id") String field,
            @RequestParam(name = "orderBy", defaultValue = "desc") String orderBy,
            @RequestParam(name = "adoptSign", defaultValue = "cpcontent") String adoptSign)
                    throws ParseException {
        HttpSession session = request.getSession();
        Operator user = (Operator) session.getAttribute("user");

        String name = request.getParameter("name");
        String contentType = request.getParameter("contentType");
        String status = request.getParameter("status");
        String isAdopted = request.getParameter("isAdopted");
        String exclusive = request.getParameter("exclusive");
        String createTimeBegin = request.getParameter("createTimeBegin");
        String createTimeEnd = request.getParameter("createTimeEnd");
        String declareTimeBegin = request.getParameter("declareTimeBegin");
        String declareTimeEnd = request.getParameter("declareTimeEnd");
        String onlineTimeBegin = request.getParameter("onlineTimeBegin");
        String onlineTimeEnd = request.getParameter("onlineTimeEnd");

        CPcontentQueryModel queryModel = new CPcontentQueryModel(name, contentType, status,
                isAdopted, exclusive, createTimeBegin, createTimeEnd, declareTimeBegin,
                declareTimeEnd, onlineTimeBegin, onlineTimeEnd, user.getOrgId(),adoptSign);

        Sort sort = null;
        if (orderBy.equals("asc")) {
            sort = new Sort(Direction.ASC, field);
        } else if (orderBy.equals("desc")) {
            sort = new Sort(Direction.DESC, field);
        }
        RestfulJson response = new RestfulJson(request,
                contentService.findContentAll(queryModel, new PageRequest(page, size, sort)));

        return response;
    }

    // 待处理工单填充
    @ActionLog(operateType = Oplog.OP_FILL, objName = Oplog.OBJ_TYPE_CPCONTENT, desc = "待处理工单填充数据")
    @RequestMapping(path = "/declare/cpContent/fill", method = RequestMethod.POST)
    public JsonResponse fill(HttpServletRequest request, @RequestBody CPContentModel model) {
        JsonResponse jsonResponse = new JsonResponse();
        CPContent cpContent = contentService.findOne(model.getId());
        cpContent.setStartTime(model.getStartTime());
        cpContent.setEndTime(model.getEndTime());
        cpContent.setExternalCode(model.getExternalCode());
        cpContent.setCode(model.getCode());
        try {
            contentService.Save(cpContent);
        } catch (Exception e) {
            logger.error(e.toString(), e);
            jsonResponse.setErrorResult(e.getMessage());
        }
        request.setAttribute(Oplog.OBJ_TYPE_CPCONTENT, cpContent);
        return jsonResponse;
    }

    // 新增
    @ActionLog(operateType = Oplog.OP_ADD, objName = Oplog.OBJ_TYPE_CPCONTENT, desc = "新增{name}内容")
    @RequestMapping(path = "/declare/cpContent/save", method = RequestMethod.POST)
    public JsonResponse save(HttpServletRequest request, @RequestBody CPContentModel model) {
        JsonResponse jsonResponse = new JsonResponse();
        CPContent content = null;
        try {
            content = model.getCpContent();
            Operator user = (Operator) request.getSession().getAttribute("user");
            content.setStatus(CPContent.STATUS_WAIT_DECLARE);// 状态为待申报
            content.setIsAdopted(CPContent.ISADOPTED_INIT);// 是否采纳为初始状态
            content.setCreateTime(new Date());
            content.setOrgId(user.getOrgId());
            content.setCreateOperId(user.getId());
            content.setType(listToStr(model.getType()));
            this.contentService.Save(content);
        } catch (Exception e) {
            logger.error(e.toString(), e);
            jsonResponse.setErrorResult(e.getMessage());
            return jsonResponse;
        }
        request.setAttribute("cpcontent", content);
        return jsonResponse;
    }

    // 修改
    @CompareLog(clazz = CPContent.class,objName = Oplog.OBJ_TYPE_CPCONTENT,operateType = Oplog.OP_EDIT,desc = "修改{name}")
    @RequestMapping(path = "/declare/cpContent/edit", method = RequestMethod.POST)
    public JsonResponse edit(HttpServletRequest request, @RequestBody CPContentModel model) {
        JsonResponse jsonResponse = new JsonResponse();
        CPContent content = null;
        try {
            content = contentService.findOne(model.getId());
            if(isCurrentUserOperation(request,content)){
            	content.setName(model.getName());
                content.setContentType(model.getContentType());
                content.setExclusive(model.getExclusive());
                content.setArea(model.getArea());
                content.setType(listToStr(model.getType()));
                content.setCode(model.getCode());
                content.setExternalCode(model.getExternalCode());
                content.setActor(model.getActor());
                content.setDirector(model.getDirector());
                content.setYears(model.getYears());
                content.setRating(model.getRating());
                content.setEpisodeNum(model.getEpisodeNum());
                content.setIntro(model.getIntro());
                content.setStartTime(model.getStartTime());
                content.setEndTime(model.getEndTime());
                content.setRemarks(model.getRemarks());
                content.setLastUpdateTime(new Date());
                this.contentService.Save(content);
            }else{
            	jsonResponse.setErrorResult(null);
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
            jsonResponse.setErrorResult(e.getMessage());
            return jsonResponse;
        }
        request.setAttribute("cpcontent", content);
        return jsonResponse;
    }

    // 申报
    @ActionLog(operateType = Oplog.OP_DECLARE, objName = Oplog.OBJ_TYPE_CPCONTENT, desc = "申报{name}")
    @RequestMapping(path = "/declare/cpContent/declare", method = RequestMethod.POST)
    public CPContent declare(HttpServletRequest request, @RequestBody CPContentModel model) {
        CPContent content = null;
        try {
            content = contentService.findOne(model.getId());
            if(isCurrentUserOperation(request,content)){
            	content.setPlanOnlineTime(model.getPlanOnlineTime());// 预计上线时间
            	content.setCopyrightTime(model.getCopyrightTime());// 授权时间
            	content.setStatus(CPContent.STATUS_WAIT_ONLINE);// 状态变为待上线
            	content.setIsAdopted(CPContent.ISADOPTED_AWAIT);// 采纳状态变为待采纳
            	content.setDeclareTime(new Date());// 申报时间
            	this.contentService.Save(content);
            }else{
            	content = null;
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        request.setAttribute("cpcontent", content);
        return content;
    }

    //删除
    @CompareLog(clazz = CPContent.class,objName = Oplog.OBJ_TYPE_CPCONTENT,operateType = Oplog.OP_DELETE,desc = "删除{name}")
    @RequestMapping(path = "/declare/cpContent/delete", method = RequestMethod.GET)
    public CPContent delete(HttpServletRequest request,Long rowId) {
        CPContent content = null;
        try {
        	//判断当前数据是否属于发送该请求的用户
            content = contentService.findOne(rowId);
            if(isCurrentUserOperation(request,content)){
            	content.setStatus(CPContent.STATUS_DELETE);// 状态改为删除
	            this.contentService.Save(content);
            }else{
            	content = null;
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        request.setAttribute("cpcontent", content);
        return content;
    }

    // 上线
    @ActionLog(operateType = Oplog.OP_ONLINE, objName = Oplog.OBJ_TYPE_CPCONTENT, desc = "上线{name}")
    @RequestMapping(path = "/declare/cpContent/online", method = RequestMethod.GET)
    public CPContent online(HttpServletRequest request, Long rowId) {
        CPContent content = null;
        try {
            content = contentService.findOne(rowId);
            if(isCurrentUserOperation(request,content)){
            	content.setOnlineTime(new Date());// 上线时间
                content.setStatus(CPContent.STATUS_ONLINE);// 状态改为已上线
                this.contentService.Save(content);
            }else{
            	content = null;
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        request.setAttribute("cpcontent", content);
        return content;
    }

    // 批量申报
    @RequestMapping(path = "/declare/cpContent/batchDeclare", method = RequestMethod.POST)
    public JsonResponse batchDeclare(HttpServletRequest request, @RequestParam List<Long> ids,
            @RequestParam String copyrightTime, @RequestParam String planOnlineTime) {
        JsonResponse jsonResponse = new JsonResponse();
        Operator user = (Operator) request.getSession().getAttribute("user");
        List<String> errorList = this.contentService.batchDeclare(user,ids, copyrightTime,
                planOnlineTime);
        jsonResponse.setResult(ids.size() - errorList.size());// 成功的条数
        jsonResponse.setData(errorList);// 失败的列表
        return jsonResponse;
    }

    // 批量上线
    @RequestMapping(path = "/declare/cpContent/bathOnline", method = RequestMethod.GET)
    public JsonResponse bathOnline(HttpServletRequest request, @RequestParam List<Long> ids) {
        JsonResponse jsonResponse = new JsonResponse();
        Operator user = (Operator) request.getSession().getAttribute("user");
        List<String> errorList = this.contentService.batchOnlineAndDelect(user,ids,
                CPContent.STATUS_ONLINE);
        jsonResponse.setResult(ids.size() - errorList.size());// 成功的条数
        jsonResponse.setData(errorList);// 失败的列表
        return jsonResponse;
    }

    // 批量删除
    @RequestMapping(path = "/declare/cpContent/bathDelete", method = RequestMethod.GET)
    public JsonResponse bathDelete(HttpServletRequest request, @RequestParam List<Long> ids) {
        JsonResponse jsonResponse = new JsonResponse();
        Operator user = (Operator) request.getSession().getAttribute("user");
        List<String> errorList = this.contentService.batchOnlineAndDelect(user,ids,
                CPContent.STATUS_DELETE);
        jsonResponse.setResult(ids.size() - errorList.size());// 成功的条数
        jsonResponse.setData(errorList);// 失败的列表
        return jsonResponse;
    }

    //导出
    @ActionLog(operateType = Oplog.OP_EXPORT, objName = Oplog.OBJ_TYPE_CPCONTENT, desc = "导出Excel")
    @RequestMapping(path = "/declare/cpContent/bathExport", method = RequestMethod.GET)
    public JsonResponse bathExport(HttpServletRequest request,
            @RequestParam(name = "page", defaultValue = "0") int page,
            @RequestParam(name = "size", defaultValue = "1000000000") int size,
            @RequestParam(name = "field", defaultValue = "id") String field,
            @RequestParam(name = "orderBy", defaultValue = "desc") String orderBy,
            @RequestParam(name = "adoptSign", defaultValue = "cpcontent") String adoptSign) {
    	
    	HttpSession session = request.getSession();
        Operator user = (Operator) session.getAttribute("user");

        String name = request.getParameter("name");
        String contentType = request.getParameter("contentType");
        String status = request.getParameter("status");
        String isAdopted = request.getParameter("isAdopted");
        String exclusive = request.getParameter("exclusive");
        String createTimeBegin = request.getParameter("createTimeBegin");
        String createTimeEnd = request.getParameter("createTimeEnd");
        String declareTimeBegin = request.getParameter("declareTimeBegin");
        String declareTimeEnd = request.getParameter("declareTimeEnd");
        String onlineTimeBegin = request.getParameter("onlineTimeBegin");
        String onlineTimeEnd = request.getParameter("onlineTimeEnd");

        CPcontentQueryModel queryModel = new CPcontentQueryModel(name, contentType, status,
                isAdopted, exclusive, createTimeBegin, createTimeEnd, declareTimeBegin,
                declareTimeEnd, onlineTimeBegin, onlineTimeEnd, user.getOrgId(),adoptSign);

        Sort sort = null;
        if (orderBy.equals("asc")) {
            sort = new Sort(Direction.ASC, field);
        } else if (orderBy.equals("desc")) {
            sort = new Sort(Direction.DESC, field);
        }
        List<CPContent> list = contentService.findContentAll(queryModel, new PageRequest(page, size, sort)).getContent();
    	JsonResponse jsonResponse = new JsonResponse();
    	WriteContentExcelService writeContentExcelService = new WriteContentExcelService();
    	Map<String, String> contentTypeResult = this.enumService.getEnumMap("contentType");
    	Map<String, String> exclusiveTypeResult = this.enumService.getEnumMap("exclusive");
    	Map<String, String> statusTypeResult = this.enumService.getEnumMap("statusType");
    	Map<String, String> isAdoptedTypeResult = this.enumService.getEnumMap("isAdoptedType");
    	String fileOption = request.getSession().getServletContext().getRealPath("/")+"excel/cpcontent/";
//      String path = "/opt/product/apps/quote/excel/"; 服务器
        File file = new File(fileOption);
        String fileName;
        try {
            if(!file.exists()&&!file.isDirectory()){
                file.mkdirs();
            }
            fileName = CodeUtils.createDateSerialNo() + ".xls";
            fileOption = fileOption + fileName;
        } catch (Exception e) {
            logger.error(e.toString(),e);
            jsonResponse.setErrorResult("创建excel文件失败");
            return jsonResponse;
        }
    	writeContentExcelService.exportExcel(fileOption, list, contentTypeResult,
    			exclusiveTypeResult, statusTypeResult, isAdoptedTypeResult);
        jsonResponse.setData("/excel/cpcontent/" + fileName);
        request.setAttribute("user", user);
        return jsonResponse;
    }
    
    // 验证code是否存在
    @RequestMapping(path = "/declare/cpContent/findByCode", method = RequestMethod.GET)
    public Boolean findByCode(HttpServletRequest request, String code, String conId) {
        Long id = null;
        if (StringUtils.isNotBlank(conId)) {
            id = Long.parseLong(conId);
        }
        List<CPContent> contentList = this.contentService.findByCode(code, id);
        if (contentList.size() > 0) {
            return true;
        }
        return false;
    }

    // 验证externalCode是否存在
    @RequestMapping(path = "/declare/cpContent/findByExternalCode", method = RequestMethod.GET)
    public Boolean findByExternalCode(HttpServletRequest request, String externalCode,
            String conId) {
        Long id = null;
        if (StringUtils.isNotBlank(conId)) {
            id = Long.parseLong(conId);
        }
        List<CPContent> contentList = this.contentService.findByExternalCode(externalCode, id);
        if (contentList.size() > 0) {
            return true;
        }
        return false;
    }

    // 查找ENUM
    @RequestMapping(path = "/declare/cpContent/findEnum", method = RequestMethod.GET)
    public List<String> findEnum(HttpServletRequest request, String value, String code) {
        EnumData enumParent = enumDataRepository.getByCode(code);
        String[] values = value.split(",");
        List<String> names = new ArrayList<String>();
        for (String v : values) {
            EnumData e = this.contentService.findEnumByValue(enumParent.getId(), v);
            names.add(e.getName());
        }
        return names;
    }

    // 将list类型转为string类型
    private String listToStr(List<String> list) {
        StringBuffer types = new StringBuffer();
        for (String type : list) {
            types.append(type + ",");
        }
        return types.toString().substring(0, types.length() - 1);
    }
    
    //判断用户操作的数据是否属于该用户
    private Boolean isCurrentUserOperation(HttpServletRequest request,CPContent content){
    	Operator user = (Operator) request.getSession().getAttribute("user");
    	return user.getOrgId().longValue()==content.getOrgId().longValue();
    }

    @RequestMapping(value = "/declare/cpContent/cpContentAndOplog", method = RequestMethod.GET)
    public RestfulJson cpContentAndOplog(HttpServletRequest request,
            @RequestParam(name = "id", required = false) Long id,
            @RequestParam(name = "name", required = false) String name,
            @RequestParam(name = "operateType", required = false) String operateType,
            @RequestParam(name = "orgName", required = false) String orgName,
            @RequestParam(name = "opName", required = false) String opName,
            @RequestParam(name = "beginTime", required = false) String beginTime,
            @RequestParam(name = "endTime", required = false) String endTime,
            @RequestParam(name = "page", defaultValue = "0") int page,
            @RequestParam(name = "size", defaultValue = "10") int size) throws Exception {
        RestfulJson response;
        try {
            Object cpContentAndOplogs = contentService.search(id, name, operateType, orgName,
                    opName, beginTime, endTime, page, size);
            response = new RestfulJson(request, cpContentAndOplogs);
        } catch (Exception e) {
            logger.error(e.toString(), e);
            return new RestfulJson();
        }
        return response;
    }
}
